package com.qingzhuge.entity;

import com.alibaba.fastjson.annotation.JSONField;
import com.qingzhuge.annotation.EntityPropertyNull;
import com.qingzhuge.interfaces.IPersistable;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;

import javax.persistence.MappedSuperclass;
import javax.persistence.Transient;
import java.io.Serializable;
import java.util.Comparator;
import java.util.Objects;

/**
 * @author : zero.xiao
 * @description : 基础抽象数据模型
 * @modified : :@JsonIgnoreProperties(ignoreUnknown = true)忽略类中不存在的字段
 */
@Getter
@Setter
@MappedSuperclass
public abstract class BaseBean<PK extends Serializable> implements IPersistable<PK>, Comparator<BaseBean> {
    private static final long serialVersionUID = -5554308939380869754L;
    public static final Integer PAGE_SIZE = 10;
    public static final Integer PAGE_NO = 0;
    /**
     * 根据id是否存在判断对象是否为新对象
     * 注解@Transient，不被序列化
     *
     * @return boolean
     */
    @Transient
    @JSONField(serialize = false,deserialize = false)
    @ApiModelProperty(hidden = true)
    @EntityPropertyNull
    public boolean isNew() {
        return null == getId();
    }

    /**
     * 搜索值，查询用，非持久化
     */
    @ApiModelProperty("功能属性:搜索值")
    @Transient
    @EntityPropertyNull
    @JSONField(serialize = false)
    private transient String keyword;

    @ApiModelProperty("功能属性:搜索字段名")
    @Transient
    @EntityPropertyNull
    @JSONField(serialize = false)
    private transient String searchField;
    /**
     * 排序用，非持久化
     */
    @ApiModelProperty("功能属性:排序用")
    @Transient
    @EntityPropertyNull
    @JSONField(serialize = false)
    private transient Boolean asc;

    @ApiModelProperty("功能属性:排序字段")
    @Transient
    @EntityPropertyNull
    @JSONField(serialize = false)
    private transient String orderByField;

    @ApiModelProperty("功能属性:分页数据每页数量")
    @Transient
    @EntityPropertyNull
    @JSONField(serialize = false)
    private transient Integer size;

    @ApiModelProperty("功能属性:分页数据页码")
    @Transient
    @EntityPropertyNull
    @JSONField(serialize = false)
    private transient Integer page;

    public BaseBean() {
    }

    @Override
    public String toString() {
        return String.format("Entity of type %s with id: %s", this.getClass().getName(), getId());
    }

    @Override
    public boolean equals(Object obj) {

        if (null == obj) {
            return false;
        }

        if (this == obj) {
            return true;
        }

        if (!getClass().equals(getUserClass(obj))) {
            return false;
        }

        BaseBean<?> that = (BaseBean<?>) obj;

        return !isNew() && this.getId().equals(that.getId());
    }

    private static Class<?> getUserClass(Object instance) {
        Objects.requireNonNull(instance, "Instance must not be null");
        return getUserClass(instance.getClass());
    }

    private static Class<?> getUserClass(Class<?> clazz) {
        if (clazz.getName().contains("$$")) {
            Class<?> superclass = clazz.getSuperclass();
            if (superclass != null && Object.class != superclass) {
                return superclass;
            }
        }

        return clazz;
    }

    @Override
    public int compare(BaseBean o1, BaseBean o2) {
        if (o1.getId() != null && o2.getId() != null) {
            if (o1.getId() instanceof Integer && o2.getId() instanceof Integer) {
                return (Integer) o1.getId() - (Integer) o2.getId();
            } else if (o1.getId() instanceof Long && o2.getId() instanceof Long) {
                return (int) ((Long) o1.getId() - (Long) o2.getId());
            } else if (o1.getId() instanceof String && o2.getId() instanceof String) {
                o1.getId().toString().compareTo(o2.getId().toString());
            }
        }
        return 0;
    }
}